package com.heima.admin.service.impl;

import java.util.Date;

import com.alibaba.fastjson.JSONArray;
import com.heima.admin.feign.ArticleFeign;
import com.heima.admin.feign.WemediaFeign;
import com.heima.admin.mapper.AdSensitiveMapper;
import com.heima.admin.service.AdChannelService;
import com.heima.admin.service.WemediaNewsAutoScanService;
import com.heima.common.aliyun.GreeTextScan;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.constans.message.ArticleForEsConstants;
import com.heima.common.fastdfs.FastDFSClient;
import com.heima.model.admin.pojos.AdChannel;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.article.pojos.ApArticleContent;
import com.heima.model.article.pojos.ApAuthor;
import com.heima.model.media.pojos.WmNews;
import com.heima.model.media.pojos.WmUser;
import com.heima.search.utils.common.SensitiveWordUtil;
//import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class WemediaNewsAutoScanServiceImpl implements WemediaNewsAutoScanService {
    @Autowired
    private WemediaFeign wemediaFeign;
    @Value("${fdfs.url}")
    private String fileServerUrl;

    @Override
//    @GlobalTransactional
    public void autoScanByMediaNewsId(Integer id) {
        //判断id是否为空
        if (id == null) {
            return;
        }
        //根据id通过feign去Wemedia去找WmNews
        WmNews wmNews = wemediaFeign.findById(id);

        //判断wmNews是否存在
        if (wmNews == null) {
            log.error("所要审核的文章不存在，id·为==>{}", id);
            return;
        }

        //根据文章状态做出相对应的处理
        Short status = wmNews.getStatus();
        long time = wmNews.getPublishTime().getTime();

        if ((status == 4 || status == 8) && time <= System.currentTimeMillis()) {
            //对文章进行发布
            saveAppArticle(wmNews);
        }
        //对待审核的文章进行审核
        if (status == 1) {
            //对文章的文字和图片进行解析
            Map<String, Object> textAndImages = handleTextAndImages(wmNews);
            //对文本信息用阿里云进行审核
            if (textAndImages.get("text") != null) {
                Boolean textFlag = handleTextScan((String) textAndImages.get("text"), wmNews);
                if (!textFlag) return;
            }
            //对图片信息用阿里云进行审核
            if (textAndImages.get("images") != null) {
                Boolean imagesFlag = handleImagesScan((List<String>) textAndImages.get("images"), wmNews);
                if (!imagesFlag) return;
            }
            //用自己的FDA进行审核
            if (textAndImages.get("text") != null) {
                //         ==> 如果查询内容中包含敏感词 修改为2 审核失败
                boolean sensitiveResult = handleSensitive((String) textAndImages.get("text"), wmNews);
                if (!sensitiveResult) return;
            }
            if (time > System.currentTimeMillis()) {
                //修改状态为8
                updateWmNews(wmNews, (short) 8, "审核通过");
            }

            saveAppArticle(wmNews);


        }


    }
    @Autowired
    KafkaTemplate kafkaTemplate;

    private void saveAppArticle(WmNews wmNews) {
        ApArticle apArticle = saveArticle(wmNews);
        saveArticleConfig(apArticle);
        saveArticleContent(wmNews, apArticle);
        kafkaTemplate.send(ArticleForEsConstants.ARTICLE_ELASTICSEARCH_ADD,String.valueOf(apArticle.getId()));

    }

    private void saveArticleContent(WmNews wmNews, ApArticle apArticle) {
        ApArticleContent apArticleContent = new ApArticleContent();
        apArticleContent.setContent(wmNews.getContent());
        apArticleContent.setArticleId(apArticle.getId());
        articleFeign.saveArticleContent(apArticleContent);
    }

    private void saveArticleConfig(ApArticle apArticle) {
        ApArticleConfig apArticleConfig = new ApArticleConfig();

        apArticleConfig.setIsComment(true);
        apArticleConfig.setIsForward(true);
        apArticleConfig.setIsDown(false);
        apArticleConfig.setIsDelete(false);

        apArticleConfig.setArticleId(apArticle.getId());
        articleFeign.saveArticleConfig(apArticleConfig);

    }

    @Autowired
    ArticleFeign articleFeign;
    @Autowired
    AdChannelService adChannelService;

    private ApArticle saveArticle(WmNews wmNews) {
        ApArticle apArticle = new ApArticle();

        apArticle.setTitle(wmNews.getTitle());
        WmUser wmUser = wemediaFeign.findWmUserById(Long.valueOf(wmNews.getUserId()));
        ApAuthor apAuthor = articleFeign.findAuthorByUserId(String.valueOf(wmUser.getApUserId()));


        apArticle.setAuthorId(Long.valueOf(apAuthor.getId()));
        apArticle.setAuthorName(apAuthor.getName());
        AdChannel adChannel = adChannelService.getById(wmNews.getChannelId());


        apArticle.setChannelId(adChannel.getId());
        apArticle.setChannelName(adChannel.getName());
        apArticle.setLayout(wmNews.getType());
        apArticle.setFlag((byte) 0);
        apArticle.setImages(wmNews.getImages());
        apArticle.setLabels(wmNews.getLabels());
        apArticle.setCreatedTime(new Date());
        apArticle.setPublishTime(wmNews.getPublishTime());

        ApArticle apArticle1 = articleFeign.saveArticle(apArticle);
        wmNews.setArticleId(apArticle1.getId());
        //修改状态为9并发布
        updateWmNews(wmNews, (short) 9, "文章发布");

        return apArticle1;
    }

    @Autowired
    AdSensitiveMapper adSensitiveMapper;

    private boolean handleSensitive(String text, WmNews wmNews) {
        List<String> sensitive = adSensitiveMapper.findAllSensitive();
        SensitiveWordUtil.initMap(sensitive);
        log.info("加载完敏感词：{}", sensitive);
        Map<String, Integer> integerMap = SensitiveWordUtil.matchWords(text);
        if (integerMap != null && integerMap.size() > 0) {
            updateWmNews(wmNews, (short) 2, "文章内容中有违规信息，审核失败");
            log.error("审核失败有敏感词：{}", integerMap);
            return false;
        }
        return true;
    }

    @Autowired
    private GreenImageScan greenImageScan;
    @Autowired
    private FastDFSClient fastDFSClient;

    private Boolean handleImagesScan(List<String> images, WmNews wmNews) {
        List<byte[]> imageByteList = new ArrayList<>();
        List<String> collect = images.stream().map(image ->
                image.replace(fileServerUrl, "")
        ).collect(Collectors.toList());

        for (String s : collect) {
            int index = s.indexOf("/");
            String groupName = s.substring(0, index);
            String path = s.substring(index + 1);

            try {
                byte[] downloadImage = fastDFSClient.download(groupName, path);
                imageByteList.add(downloadImage);
            } catch (IOException e) {
                e.printStackTrace();
                log.error("fastdfs下载图片失败==> group={} path={}", groupName, path);
            }
            if (imageByteList != null) {
                try {
                    Map map = greenImageScan.imageScan(imageByteList);
                    String suggestion = (String) map.get("suggestion");
                    if (suggestion.equals("pass")) {

                    }
                    if (suggestion.equals("review")) {
                        updateWmNews(wmNews, (short) 3, "图片内容中有不确定因素，需要人工审核");
                        return false;
                    }
                    if (suggestion.equals("block")) {
                        updateWmNews(wmNews, (short) 2, "图片内容中有违规，审核失败");
                        return false;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("图片审核失败原因为{}", e.getMessage());
                }
            }
        }


        return true;


    }

    @Autowired
    private GreeTextScan greeTextScan;

    private Boolean handleTextScan(String text, WmNews wmNews) {
        Map map = null;
        try {
            map = greeTextScan.greeTextScan(text);
            if (map != null) {
                String suggestion = (String) map.get("suggestion");
                if (suggestion.equals("pass")) {
                    return true;
                }
                if (suggestion.equals("review")) {
                    updateWmNews(wmNews, (short) 3, "文章内容中有不确定因素，需要人工审核");
                }
                if (suggestion.equals("block")) {
                    updateWmNews(wmNews, (short) 2, "文章内容中有违规信息，审核失败");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("文本审核失败原因为{}", e.getMessage());
        }

        return false;
    }

    private void updateWmNews(WmNews wmNews, short status, String reason) {
        wmNews.setStatus(status);
        wmNews.setReason(reason);
        wemediaFeign.updateWmNews(wmNews);
    }

    private Map<String, Object> handleTextAndImages(WmNews wmNews) {
        StringBuilder textSb = new StringBuilder();
        List<String> imageList = new ArrayList<>();
        String title = wmNews.getTitle();
        String content = wmNews.getContent();
        //[{"type":"image","value":"http://192.168.200.130/group1/M00/00/00/wKjIgl9W6iOAD2doAAFY4E1K7-g384.png"},
        // {"type":"text","value":"全国抗击新冠肺炎疫情表彰大会开始15家“文化会客厅”展现产业发展的集群效应全球疫情简报:印度新冠确诊病例超420万 升至全球第二中方提出《全球数据安全倡议》"}]
        List<Map> mapList = JSONArray.parseArray(content, Map.class);
        for (Map map : mapList) {
            if (map.get("type").equals("text")) {
                String value = (String) map.get("value");
                textSb.append(value);
            }
            if (map.get("type").equals("image")) {
                imageList.add((String) map.get("value"));
            }

        }
        textSb.append(title);
        String images = wmNews.getImages();
        if (StringUtils.isNotBlank(images)) {
            String[] split = images.split(",");
            imageList.addAll(Arrays.asList(split));
        }
        Map<String, Object> map = new HashMap<>();
        map.put("text", textSb.toString());
        map.put("images", imageList);


        return map;
    }
}
